package com.takeeasy.platform.facade.servlet;

import com.takeeasy.platform.action.IAction;
import com.takeeasy.platform.annotation.Action;
import com.takeeasy.platform.cache.SystemDataCache;
import com.takeeasy.platform.util.ActionNameFileFilter;
import com.takeeasy.platform.util.FileUtil;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ActionLoader {

    private static Logger logger = LoggerFactory.getLogger(ActionLoader.class);

    public void load() {
        logger.debug("缓存业务逻辑处理类...");
        String classPath = FileUtil.getClassRootPath();
        File classPathFile = new File(classPath);
        this.listFile(classPathFile);
    }

    @SuppressWarnings("unchecked")
	private void loadFile(File file) {
        try {
            String filePath = file.getCanonicalPath();
            ClassLoader loader = this.getClass().getClassLoader();
            String appPath = FileUtil.getClassRootPath();
            String classPath = filePath.substring(filePath.indexOf(appPath) + appPath.length(), filePath.lastIndexOf(".class"));
            Class<?> clz = loader.loadClass(classPath.replace(FileUtil.FILE_SEPARATOR, "."));
            if (IAction.class.isAssignableFrom(clz)) {
                loadFileAnnotation((Class<IAction>) clz);
            }
        } catch (ClassNotFoundException e) {
            logger.error("加载类：" + file.getAbsolutePath() + "失败");
        } catch (IOException ex) {
            logger.error("读取类：" + file.getAbsolutePath() + "失败");
        }
    }

    private void loadFileAnnotation(Class<? extends IAction> clz) {
        Action actionAnn = clz.getAnnotation(Action.class);
        if (actionAnn != null) {
            this.cacheData(actionAnn, clz);
        }
    }

    private void cacheData(Action actionAnn, Class<? extends IAction> clz) {
        String actionName = actionAnn.name();
        logger.debug("缓存逻辑处理类：" + actionName + "|" + clz.getName());
        if (SystemDataCache.ACTION_CACHE == null) {
            Map<String, Class<? extends IAction>> cacheMap = new HashMap<>();
            SystemDataCache.ACTION_CACHE = new HashMap<>();
            SystemDataCache.ACTION_CACHE.put(SystemDataCache.DEFAULT_ACTION_DOMAIN, cacheMap);
        }
        Map<String, Class<? extends IAction>> cachedMap = SystemDataCache.ACTION_CACHE.get(SystemDataCache.DEFAULT_ACTION_DOMAIN);
        cachedMap.put(actionName, clz);
    }

    private void listFile(File classPathFile) {
        File[] actionFile = classPathFile.listFiles(new ActionNameFileFilter());
        List<File> fileList = Arrays.asList(actionFile);
        fileList.forEach(file -> {
            if (file.isDirectory()) {
                listFile(file);
            } else {
                this.loadFile(file);
            }
        });
    }

    public static void main(String[] args) {
        ActionLoader la = new ActionLoader();
        la.load();
    }
}
